﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using com.opttek.optquest;
namespace ConsoleApplication1
{
    public partial class MainForm : Form
    {
        public int license = 997657957;
        public string rootpath = "..\\..\\..\\SetG\\SetG\\";
        public string resultspath = "..\\..\\..\\Results\\";
        public bool setupcost = false;
        public int stopiterations = 120 ;
        public bool useiterations = true;
        public int stopmin = 10;
        public int bincount = 1000;
        public int evaluators = System.Environment.ProcessorCount;
        private bool running = false;

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            //Set all the default values
            licensetextbox.Text = license.ToString();
            intextbox.Text = rootpath;
            outtextbox.Text = resultspath;
            setupcheck.Checked = setupcost;

            binCount.Maximum = 10000;
            binCount.Minimum = 0;

            binCount.Value = bincount;

            processorCount.Maximum = System.Environment.ProcessorCount;
            processorCount.Minimum = 1;
            processorCount.Value = System.Environment.ProcessorCount;
            
            if (useiterations)
            {
                iterations.Checked = true;
                stopnumeric.Maximum = 1000;
                stopnumeric.Minimum = 10;
                stopnumeric.Value = stopiterations;
            }
            else
            {
                time.Checked = true;
                stopnumeric.Maximum = 60;
                stopnumeric.Minimum = 1;
                stopnumeric.Value = stopmin;
            }

            
        }


        private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            ProgressPacket packet = e.UserState as ProgressPacket;
            if (packet.toConsole)
            {
                txtOutput.Text += packet.output;
                txtOutput.Refresh();
            }
            else
            {
                COptQuestSolution s = packet.solution;
                progressBar1.Value = e.ProgressPercentage;
                string[] row = new string[gridView.ColumnCount];
                row[0] = s.GetIteration().ToString();
                row[1] = s.GetObjectiveValue().ToString();
                row[2] = s.GetVariableValue(MainProgram.getInstance().optquest.salesuc).ToString();
                row[3] = s.GetVariableValue(MainProgram.getInstance().optquest.prodcostuc).ToString();
                row[4] = s.GetVariableValue(MainProgram.getInstance().optquest.holdcostuc).ToString();
                row[5] = s.GetVariableValue(MainProgram.getInstance().optquest.backordercostuc).ToString();
                row[6] = s.GetVariableValue(MainProgram.getInstance().optquest.tarinvcostuc).ToString();
                row[7] = s.GetVariableValue(MainProgram.getInstance().optquest.serviceleveluc).ToString();
                if(setupcost)
                    row[8] = s.GetVariableValue(MainProgram.getInstance().optquest.setupcostuc).ToString();
                gridView.Rows.Add(row);

            }

        }

        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            running = false;
            if (e.Cancelled)
            {
                MessageBox.Show("Unexpexted Error! ", "Aborting",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;

            }

            if (progressBar1.Value != 100)
                progressBar1.Value = 100;
            COptQuestSolution s = e.Result as COptQuestSolution;
            string[] row = new string[gridView.ColumnCount];
            row[0] = s.GetIteration().ToString();
            row[1] = s.GetObjectiveValue().ToString();
            row[2] = s.GetVariableValue(MainProgram.getInstance().optquest.salesuc).ToString();
            row[3] = s.GetVariableValue(MainProgram.getInstance().optquest.prodcostuc).ToString();
            row[4] = s.GetVariableValue(MainProgram.getInstance().optquest.holdcostuc).ToString();
            row[5] = s.GetVariableValue(MainProgram.getInstance().optquest.backordercostuc).ToString();
            row[6] = s.GetVariableValue(MainProgram.getInstance().optquest.tarinvcostuc).ToString();
            row[7] = s.GetVariableValue(MainProgram.getInstance().optquest.serviceleveluc).ToString();
            if (setupcost)
                row[8] = s.GetVariableValue(MainProgram.getInstance().optquest.setupcostuc).ToString();
            gridView.Rows.Add(row);
            TimeSpan now = DateTime.Now - MainProgram.getInstance().basestart;
            float totalmin = (float)now.TotalMinutes;
            MessageBox.Show("Simulation Ended in "+totalmin.ToString("0.00")+" minutes!\n Best Solution found: "+s.GetObjectiveValue().ToString("0.00") ,"Simulation Succesful!");
        }

        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {

            FormConfig config = e.Argument as FormConfig;
            MainProgram.getInstance().SaveConfig(config);
            try
            {
                MainProgram.getInstance().Execute();
                e.Result = MainProgram.getInstance().optquest.GetBestSolution();
            }
            catch {
                e.Cancel = true;
                
            }
                


        }

        private void iterations_CheckedChanged(object sender, EventArgs e)
        {
            if (iterations.Checked)
            {
                iterations.Checked = true;
                useiterations = true;
                
                stopnumeric.Maximum = 1000;
                stopnumeric.Minimum = 10;

                if (stopiterations > 1000 || stopiterations < 10)
                    stopiterations = 1000;
                stopnumeric.Value = stopiterations;
            }
            else 
            {
                useiterations = false;
                time.Checked = true;
                stopnumeric.Maximum = 60;
                stopnumeric.Minimum = 1;

                if (stopmin > 60 || stopmin < 1)
                    stopmin = 60;

                stopnumeric.Value = stopmin;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (running)
                return;
            running = true;
            rootpath = intextbox.Text;
            resultspath = outtextbox.Text;
            evaluators = (int)processorCount.Value;
            stopiterations = (int)stopnumeric.Value;
            stopmin = (int)stopnumeric.Value;
            setupcost = setupcheck.Checked;
            bincount = (int)binCount.Value;
            if (setupcost)
            {
                if(!gridView.Columns.Contains("setupcost"))
                    gridView.Columns.Add("setupcost", "Setup Cost");
            }
            else
            {
                if (gridView.Columns.Contains("setupcost"))
                    gridView.Columns.Remove("setupcost");
            }

            FormConfig config = new FormConfig(license, evaluators, rootpath,
                resultspath, setupcost, bincount);
            if (useiterations)
                config.setStopIterations(stopiterations);
            else
                config.setStopTime(stopmin);

            if (progressBar1.Value != 0)
            {

                int totalrows = gridView.Rows.Count;
               for (int i = 0; i < totalrows; i++)
                {
                    if (!gridView.Rows[0].IsNewRow)
                        gridView.Rows.RemoveAt(0);  
                    
                }
                progressBar1.Value = 0;
                txtOutput.ResetText();
            }
             

            worker.RunWorkerAsync(config);
        }

        private void openDialog_HelpRequest(object sender, EventArgs e)
        {

        }

        private void openbutton_Click(object sender, EventArgs e)
        {

            openDialog.SelectedPath = Environment.CurrentDirectory;
            DialogResult result =  openDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                intextbox.Text = openDialog.SelectedPath;
            }
            
        }

        private void savebutton_Click(object sender, EventArgs e)
        {
            saveDialog.SelectedPath = Environment.CurrentDirectory;
            DialogResult result = saveDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                outtextbox.Text = saveDialog.SelectedPath;
            }
        }


    }
}
